package com.spddr.pmos.rpt.impl;

import java.util.List;
import java.util.stream.Collectors;

import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.Months;
import org.joda.time.Period;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.spddr.pmos.jpa.ObjectDataStorage;
import com.spddr.pmos.rpt.RptGeneral;
import com.spddr.pmos.rpt.pojo.CellValue;

import cn.seqdata.echarts.Option;
import cn.seqdata.echarts.axis.CategoryAxis;
import cn.seqdata.echarts.axis.ValueAxis;
import cn.seqdata.echarts.series.Line;
import cn.seqdata.tags.Point;
import cn.seqdata.tags.RegularValues;
import cn.seqdata.tags.common.IdTags;

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class RtpGeneralImpl extends AbstractPivotChartImpl implements RptGeneral {

	protected Period intervalOfStorage() {
		List<ObjectDataStorage> storages = storageRepos.findByIdObjectTypeAndIdMetric(level.id, metric);
		return storages.stream().map(x -> x.getId().getInterval())
				.filter(n -> n.toStandardMinutes().isLessThan(interval.toStandardMinutes()))
				.max((a, b) -> a.toStandardMinutes().getMinutes() - b.toStandardMinutes().getMinutes())
				.orElse(Hours.ONE.toPeriod());
	}

	@Override
	public List<CellValue> loadPivot() {
		RegularValues<IdTags, Point<IdTags>> values = load(level.id, id, metric);
		return values.getValue().getValues().stream().map(x -> new CellValue(values.getKey(), x, null, null))
				.collect(Collectors.toList());
	}

	@Override
	public Option chart() {
		Option option = new Option();
		option.legend().data("曲线");
		option.title().show(false);

		Period period = intervalOfStorage();
		CategoryAxis xAxis = new CategoryAxis().show(true);
		if (Days.ONE.toPeriod().toStandardMinutes().isGreaterThan(period.toStandardMinutes())) {
			xAxis.setFunc(String.format("Admin.Array.minutes(%d, 'H:i', '%s', '%s')",
					period.toStandardMinutes().getMinutes(), getStartTime(), getEndTime()));
		} else if (Days.ONE.toPeriod().equals(period)) {
			xAxis.setFunc(String.format("Admin.Array.days(%d, 'm-d', '%1$s', '%2$s')",
					period.toStandardDays().getDays(), getStartTime(), getEndTime()));
		} else if (Months.ONE.toPeriod().equals(period)) {
			xAxis.setFunc(String.format("Admin.Array.months(1, 'm', '%1$s', '%2$s')", getStartTime(), getEndTime()));
		}
		option.xAxis(xAxis);

		option.yAxis(new ValueAxis().show(true));

		Line line = new Line();
		option.series().add(line);

		RegularValues<IdTags, Point<IdTags>> values = load(level.id, id, metric, period);
		values.getValue().getValues().forEach(x -> {
			line.data().add(x.getValue());
		});

		return option;
	}

}
